/*************************************************************
 * File: MenuServiceImpl.java
 * Copyright (c) 2012
 * Author: Huang Shaobin
 * Email: Shaobin.Software@gmail.com Shaobin_Software@163.com 
 * Date: Feb 24, 2013
 * Description: 
 ************************************************************/

package snow.biz.system.service.impl;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;

import snow.biz.basic.service.impl.HibernateBaseServiceImpl;
import snow.biz.security.model.Privilege;
import snow.biz.system.model.Menu;
import snow.biz.system.model.User;
import snow.biz.system.service.IMenuService;
import snow.core.domain.Pagination;
import snow.core.enums.Status;
import snow.core.exceptions.BusinessException;
import snow.core.persistence.AndedConditions;
import snow.core.persistence.BinaryOperator;
import snow.core.persistence.Condition;
import snow.core.persistence.Conditions;
import snow.core.persistence.EntityHelper;
import snow.core.persistence.Order;
import snow.core.toolkit.Validator;

/**
 * 菜单相关的接口实现
 * 
 * @author Shaobin.Software@gmail.com Shaobin_Software@163.com
 * @version 1.0
 */
public class MenuServiceImpl extends HibernateBaseServiceImpl implements IMenuService {

	/**
	 * 创建菜单
	 * 
	 * @param menu
	 * @return
	 * @throws BusinessException
	 * @see snow.biz.system.service.IMenuService#createMenuFrom(snow.biz.system.model.Menu)
	 */
	public Integer createMenuFrom(Menu menu) throws BusinessException {
		final Integer id = super.save(menu, Integer.class);
		menu = searchMenuFrom(id);
		menu.resetTreeRelation();
		super.update(menu);
		return id;
	}

	/**
	 * 物理删除，慎用
	 * 
	 * @param menu
	 * @throws BusinessException
	 * @see snow.biz.system.service.IMenuService#deleteMenuFrom(snow.biz.system.model.Menu)
	 */
	public void deleteMenuFrom(Menu menu) throws BusinessException {
		Menu targetMenu = super.get(Menu.class, menu == null ? null : menu.getId());
		Validator.notNull(targetMenu, "", ""); // TODO
		super.delete(targetMenu);
	}

	private Conditions getConditionsFrom(Conditions conditions) throws BusinessException {
		final User currentUser = super.getCurrentUser();
		final Set<Privilege> privileges = new HashSet<Privilege>(currentUser.getPrivileges());
		privileges.addAll(super.find(Privilege.class, new AndedConditions()
				.addCondition(new Condition("needCheck", BinaryOperator.EQ, Privilege.NOT_NEED_CHECK)), null, -1, -1));
		final List<Menu> menus = super.find(Menu.class, new AndedConditions().addCondition(new Condition("privilege", privileges)), null, -1, -1);
		if (CollectionUtils.isNotEmpty(menus)) {
			final Set<Integer> idSet = new HashSet<Integer>();
			for (final Menu menu : menus) {
				if (menu == null) {
					continue;
				}
				final String[] treeRelation = StringUtils.split(menu.getTreeRelation(), ',');
				for (final String id : treeRelation) {
					idSet.add(Integer.valueOf(NumberUtils.toInt(id)));
				}
			}
			return new AndedConditions().addConditions(conditions).addCondition(new Condition("id", idSet));
		}
		return conditions;
	}

	/**
	 * 修改菜单
	 * 
	 * @param menu
	 * @throws BusinessException
	 * @see snow.biz.system.service.IMenuService#modifyMenuFrom(snow.biz.system.model.Menu)
	 */
	public void modifyMenuFrom(Menu menu) throws BusinessException {
		Menu targetMenu = super.get(Menu.class, menu.getId());
		Validator.isTrue(EntityHelper.validate(targetMenu), "", ""); // TODO
		try {
			BeanUtils.copyProperties(menu, targetMenu);
		} catch (BeansException e) {
			log.warn(e.getMessage(), e);
		}
		menu.resetTreeRelation();
		super.update(targetMenu);
	}

	/**
	 * 删除菜单
	 * 
	 * @param menu
	 * @throws BusinessException
	 * @see snow.biz.system.service.IMenuService#removeMenuFrom(snow.biz.system.model.Menu)
	 */
	public void removeMenuFrom(Menu menu) throws BusinessException {
		Menu targetMenu = super.get(Menu.class, menu == null ? null : menu.getId());
		Validator.isTrue(EntityHelper.validate(targetMenu), "", ""); // TODO
		targetMenu.setStatus(Status.FAILURE);
		super.update(targetMenu);
	}

	/**
	 * 获取菜单信息
	 * 
	 * @param id
	 * @return
	 * @see snow.biz.system.service.IMenuService#searchMenuFrom(java.lang.Integer)
	 */
	public Menu searchMenuFrom(Integer id) {
		try {
			return super.get(Menu.class, id);
		} catch (BusinessException e) {
			return null;
		}
	}

	/**
	 * @param conditions
	 * @param orders
	 * @param start
	 * @param limit
	 * @return
	 * @see snow.biz.system.service.IMenuService#searchMenusForPagingFrom(snow.core.persistence.Conditions, java.util.List, int, int)
	 */
	public Pagination searchMenusForPagingFrom(Conditions conditions, List<Order> orders, int start, int limit) {
		try {
			return super.findForPaging(Menu.class, getConditionsFrom(conditions), orders, start, limit);
		} catch (BusinessException e) {
			log.warn(e.getMessage(), e);
			return null;
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return null;
		}
	}

	/**
	 * @param conditions
	 * @param orders
	 * @param start
	 * @param limit
	 * @return
	 * @see snow.biz.system.service.IMenuService#searchMenusFrom(snow.core.persistence.Conditions, java.util.List, int, int)
	 */
	public List<Menu> searchMenusFrom(Conditions conditions, List<Order> orders, int start, int limit) {
		try {
			return super.find(Menu.class, getConditionsFrom(conditions), orders, start, limit);
		} catch (BusinessException e) {
			log.warn(e.getMessage(), e);
			return null;
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return null;
		}
	}

}
